package apis

import (
	"github.com/gin-gonic/gin"
	"tylnmall/models"
	"common/logger"
	"net/http"
	"tylnmall/constant"
	"github.com/jinzhu/gorm"
	"errors"
	"fmt"
	"tylnmall/service"
	"math"
	"strings"
	"strconv"
)

func CarListApi(c *gin.Context) {
	type param struct {
		Id   int `json:"id" form:"id"`
		Page int `json:"page" form:"page"`
	}
	type sc struct {
		Id                 int     `json:"id" form:"id"`
		Number             int     `json:"number" form:"number"` //数量
		CommodityId        int     `json:"commodity_id" form:"commodity_id"`
		CommodityName      string  `json:"commodity_name"`
		CommodityUnitPrice float32 `json:"commodity_unit_price"`
		CommodityUrl       string  `json:"commodity_url"`
	}
	var p param
	var err error
	var cars []*models.Shoppingcar
	if err = c.Bind(&p); err != nil {
		logger.Error(err)
		c.JSON(http.StatusOK, gin.H{"err_code": constant.ErrorParamWrong, "err_msg": constant.TranslateErrCode(constant.ErrorParamWrong)})
		return
	}
	db := c.MustGet("ty").(*gorm.DB)
	var count float64
	if err := db.Where("user_id = ?", p.Id).Model(&models.Shoppingcar{}).Count(&count).Error; err != nil {
		logger.Error(err)
		c.AbortWithStatus(http.StatusInternalServerError)
		return
	}
	if p.Page == 0 {
		p.Page = 1
	} else if float64(p.Page) > math.Ceil(count/1000.0) {
		p.Page = 1
	}
	if err = db.Limit(1000).Offset((p.Page - 1) * 1000).Where("user_id = ?", p.Id).Find(&cars).Error; err != nil {
		logger.Error(err)
		err = errors.New("user not found")
		logger.Error(err)
		c.JSON(http.StatusOK, gin.H{"err_code": constant.ErrorDB, "err_msg": constant.TranslateErrCode(constant.ErrorDB)})
		return
	}
	var list []*sc
	fmt.Println(len(cars))
	for _, car := range cars {
		var l sc
		var commodity models.Commodity
		l.Id = car.Id
		l.Number = car.Number
		if err = db.Where("id = ?", car.CommodityId).Find(&commodity).Error; err != nil {
			logger.Error(err)
			err = errors.New("commodity not found")
			logger.Error(err)
			c.JSON(http.StatusOK, gin.H{"err_code": constant.ErrorDB, "err_msg": constant.TranslateErrCode(constant.ErrorDB)})
			return
		}
		l.CommodityId = car.CommodityId
		l.CommodityName = commodity.Name
		l.CommodityUnitPrice = commodity.UnitPrice
		l.CommodityUrl = commodity.Image
		list = append(list, &l)
	}
	c.JSON(http.StatusOK, gin.H{"list": list, "pageNum": math.Ceil(count / 1000.0)})
}

//添加商品到购物车  如果商品已经存在,则直接更新数量
func CarAddApi(c *gin.Context) {
	type param struct {
		Userid      int `json:"userid" form:"userid"`
		Commodityid int `json:"commodityid" form:"commodityid"`
		Num         int `json:"num" form:"num"`
	}
	var p param
	var err error
	var ca models.Shoppingcar
	if err = c.Bind(&p); err != nil {
		logger.Error(err)
		c.JSON(http.StatusOK, gin.H{"err_code": constant.ErrorParamWrong, "err_msg": constant.TranslateErrCode(constant.ErrorParamWrong)})
		return
	}
	db := c.MustGet("ty").(*gorm.DB)
	if b, commodity := service.IsCommodity(db, p.Commodityid); !b {
		fmt.Println(commodity)
		err = errors.New("commodity is not found")
		logger.Error(err)
		c.JSON(http.StatusOK, gin.H{"err_code": constant.ErrorCommodity, "err_msg": constant.TranslateErrCode(constant.ErrorCommodity)})
		return
	}
	if err = db.Where("user_id = ? and commodity_id = ?", p.Userid, p.Commodityid).First(&ca).Error; err != nil {
		var car models.Shoppingcar
		car.UserId = p.Userid
		car.CommodityId = p.Commodityid
		car.Number = p.Num

		if err = db.Create(&car).Error; err != nil {
			logger.Error(err)
			err = errors.New("user not found")
			logger.Error(err)
			c.JSON(http.StatusOK, gin.H{"err_code": constant.ErrorDB, "err_msg": constant.TranslateErrCode(constant.ErrorDB)})
			return
		}
	}
	fmt.Println(ca.Id)
	//var car models.Shoppingcar
	if ca.Id == 0 {
		//car.UserId = p.Userid
		//car.CommodityId = p.Commodityid
		//car.Number = p.Num
		//
		//if err = db.Create(&car).Error; err != nil {
		//	logger.Error(err)
		//	err = errors.New("user not found")
		//	logger.Error(err)
		//	c.JSON(http.StatusOK, gin.H{"err_code": constant.ErrorDB, "err_msg": constant.TranslateErrCode(constant.ErrorDB)})
		//	return
		//}
	} else {
		ca.Number += p.Num
		if err = db.Model(&ca).Update("number", ca.Number).Error; err != nil {
			logger.Error(err)
			err = errors.New("car not found")
			logger.Error(err)
			c.JSON(http.StatusOK, gin.H{"err_code": constant.ErrorDB, "err_msg": constant.TranslateErrCode(constant.ErrorDB)})
			return
		}
	}
	c.JSON(http.StatusOK, gin.H{"status": "success"})
}

//修改购物车商品数量
func CarUpdate(c *gin.Context) {
	type param struct {
		Id  int `json:"id" form:"id"`
		Num int `json:"num" form:"num"`
	}
	var err error
	var p param
	var car models.Shoppingcar
	if err = c.Bind(&p); err != nil {
		logger.Error(err)
		c.JSON(http.StatusOK, gin.H{"err_code": constant.ErrorParamWrong, "err_msg": constant.TranslateErrCode(constant.ErrorParamWrong)})
		return
	}
	db := c.MustGet("ty").(*gorm.DB)
	if err = db.Where("id = ?", p.Id).Find(&car).Error; err != nil {
		logger.Error(err)
		err = errors.New("car not found")
		logger.Error(err)
		c.JSON(http.StatusOK, gin.H{"err_code": constant.ErrorDB, "err_msg": constant.TranslateErrCode(constant.ErrorDB)})
		return
	}
	if err = db.Model(&car).Update("number", p.Num).Error; err != nil {
		logger.Error(err)
		err = errors.New("car not found")
		logger.Error(err)
		c.JSON(http.StatusOK, gin.H{"err_code": constant.ErrorDB, "err_msg": constant.TranslateErrCode(constant.ErrorDB)})
		return
	}
	c.JSON(http.StatusOK, gin.H{"status": "success"})

}

//删除购物车记录
func CarDelApi(c *gin.Context) {
	type param struct {
		Ids string `json:"list" form:"list"`
	}
	var p param
	var err error
	var car models.Shoppingcar
	if err = c.Bind(&p); err != nil {
		logger.Error(err)
		c.JSON(http.StatusOK, gin.H{"err_code": constant.ErrorParamWrong, "err_msg": constant.TranslateErrCode(constant.ErrorParamWrong)})
		return
	}
	fmt.Println(p.Ids)
	var list []string
	list = strings.Split(p.Ids, ",")
	fmt.Println(list)
	if len(list) <= 0 {
		logger.Error(err)
		c.JSON(http.StatusOK, gin.H{"err_code": constant.ErrorParamWrong, "err_msg": constant.TranslateErrCode(constant.ErrorParamWrong)})
		return
	}
	db := c.MustGet("ty").(*gorm.DB)
	for _, idstring := range list {
		id, err := strconv.Atoi(idstring)
		if err != nil {
			logger.Error(err)
			c.JSON(http.StatusOK, gin.H{"err_code": constant.ErrorParamWrong, "err_msg": constant.TranslateErrCode(constant.ErrorParamWrong)})
			return
		}
		b, iscar := service.IsCar(db, id)
		if !b || iscar.Id == 0 {
			logger.Error(err)
			err = errors.New("car not found")
			logger.Error(err)
			c.JSON(http.StatusOK, gin.H{"err_code": constant.ErrorDB, "err_msg": constant.TranslateErrCode(constant.ErrorDB)})
			return
		}
		if err = db.Where("id = ?", id).Delete(&car).Error; err != nil {
			logger.Error(err)
			err = errors.New("car not found")
			logger.Error(err)
			c.JSON(http.StatusOK, gin.H{"err_code": constant.ErrorDB, "err_msg": constant.TranslateErrCode(constant.ErrorDB)})
			return
		}
	}
	c.JSON(http.StatusOK, gin.H{"status": "success"})
}

//购物车批量购买
func CarBuyApi(c *gin.Context) {
	type param struct {
		Ids string `json:"list" form:"list"`
	}
	var p param
	var err error
	if err = c.Bind(&p); err != nil {
		logger.Error(err)
		c.JSON(http.StatusOK, gin.H{"err_code": constant.ErrorParamWrong, "err_msg": constant.TranslateErrCode(constant.ErrorParamWrong)})
		return
	}
	fmt.Println(p.Ids)
	var list []string
	list = strings.Split(p.Ids, ",")
	fmt.Println(list)
	if len(list) <= 0 {
		logger.Error(err)
		c.JSON(http.StatusOK, gin.H{"err_code": constant.ErrorParamWrong, "err_msg": constant.TranslateErrCode(constant.ErrorParamWrong)})
		return
	}
	db := c.MustGet("ty").(*gorm.DB)
	for _, idstring := range list {
		id, err := strconv.Atoi(idstring)
		if err != nil {
			logger.Error(err)
			c.JSON(http.StatusOK, gin.H{"err_code": constant.ErrorParamWrong, "err_msg": constant.TranslateErrCode(constant.ErrorParamWrong)})
			return
		}
		b, iscar := service.IsCar(db, id)
		if !b || iscar.Id == 0 {
			logger.Error(err)
			err = errors.New("car not found")
			logger.Error(err)
			c.JSON(http.StatusOK, gin.H{"err_code": constant.ErrorDB, "err_msg": constant.TranslateErrCode(constant.ErrorDB)})
			return
		}
		var purchase models.PurchaseHistory
		purchase.CommodityId = iscar.CommodityId
		purchase.UserId = iscar.UserId
		purchase.Number = iscar.Number
		if err = db.Save(&purchase).Error; err != nil {
			logger.Error(err)
			err = errors.New("car not found")
			logger.Error(err)
			c.JSON(http.StatusOK, gin.H{"err_code": constant.ErrorDB, "err_msg": constant.TranslateErrCode(constant.ErrorDB)})
			return
		}
		if err = db.Delete(&iscar).Error; err != nil {
			logger.Error(err)
			err = errors.New("car not found")
			logger.Error(err)
			c.JSON(http.StatusOK, gin.H{"err_code": constant.ErrorDB, "err_msg": constant.TranslateErrCode(constant.ErrorDB)})
			return
		}

	}
	c.JSON(http.StatusOK, gin.H{"status": "success"})
}
